package com.admin.web;

import com.admin.base.BaseController;
import com.admin.base.Response;
import com.admin.base.ResponseType;
import com.admin.exam.entity.*;
import com.admin.exam.service.HospitalService;
import com.admin.exam.service.PersonInfoService;
import com.admin.exam.service.QuestionService;
import com.admin.exam.vo.query.HospitalQuery;
import com.admin.exam.vo.query.QuestionQuery;
import com.admin.system.auth.entity.LoginToken;
import com.admin.system.entity.SystemIcon;
import com.admin.system.entity.SystemResource;
import com.admin.system.entity.SystemUser;
import com.admin.system.service.SystemIconService;
import com.admin.system.service.SystemResourceService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author : alex
 * @date : 2020/7/26
 */
@Controller
@RequestMapping(value = "/web")
public class WebController extends BaseController {
    @Autowired
    HospitalService hospitalService;
    @Autowired
    PersonInfoService personInfoService;
    @Autowired
    QuestionService questionService;

    /**
     * 个人信息
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/hospitalInfo")
    @ResponseBody
    @CrossOrigin
    public Response hospitalInfo(HttpServletRequest request, HttpServletResponse response) {
        List<Hospital> hospitals = hospitalService.listByConditions(new HospitalQuery());

        return Response.ok(hospitals);
    }

    /**
     * 个人信息
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/toExam")
    @ResponseBody
    @CrossOrigin
    public Response toExam(HttpServletRequest request, HttpServletResponse response) {
        PersonInfo personInfo = new PersonInfo();
        personInfo.setHospital(Integer.valueOf(request.getParameter("hospital")));
        personInfo.setCity(request.getParameter("city"));
        personInfo.setDepartment(request.getParameter("department"));
        personInfo.setName(request.getParameter("name"));
        personInfo.setPhone(request.getParameter("phone"));
        personInfo.setCreateTime(LocalDateTime.now());
        try {
            personInfoService.add(personInfo);
        } catch (Exception e) {
            e.printStackTrace();
            return Response.error(-1, "无法重复参加考试");
        }

        return Response.ok();
    }

    @RequestMapping(value = "/query")
    @ResponseBody
    @CrossOrigin
    public Response query(HttpServletRequest request, HttpServletResponse response) {
        String phone = request.getParameter("phone");
        PersonInfo personInfo = personInfoService.getPersonInfoByPhone(phone);
        if (Objects.isNull(personInfo)) {
            return Response.error(-1, "该用户未参加考试");
        }
        return Response.ok();
    }

    @RequestMapping(value = "/getQuestions")
    @ResponseBody
    @CrossOrigin
    public Response getQuestions(HttpServletRequest request, HttpServletResponse response) {
        QuestionQuery query = new QuestionQuery();
        query.setSingle("true");
        List<Question> singleQuestions = questionService.listByConditions(query);
        Collections.shuffle(singleQuestions);

        query.setSingle("false");
        List<Question> multipleQuestions = questionService.listByConditions(query);
        Collections.shuffle(multipleQuestions);


        List<QuestionVo> questionVoList = new ArrayList<>();
        questionVoList.addAll(getSingleQuestions(singleQuestions));
        questionVoList.addAll(getMultipleQuestions(multipleQuestions));

        return Response.ok(questionVoList);
    }

    public List<QuestionVo> getSingleQuestions(List<Question> singleQuestions) {
        List<QuestionVo> questionVoList = new ArrayList<>();
        if (singleQuestions.isEmpty() || singleQuestions.size() < 20) {
            return questionVoList;
        }
        for (int i = 0; i < 20; i++) {
            Question question = singleQuestions.get(i);
            QuestionVo questionVo = buildVo(question);
            questionVoList.add(questionVo);
        }
        return questionVoList;
    }

    public List<QuestionVo> getMultipleQuestions(List<Question> multipleQuestions) {
        List<QuestionVo> questionVoList = new ArrayList<>();
        if (multipleQuestions.isEmpty() || multipleQuestions.size() < 5) {
            return questionVoList;
        }
        for (int i = 0; i < 5; i++) {
            Question question = multipleQuestions.get(i);
            QuestionVo questionVo = buildVo(question);
            questionVoList.add(questionVo);
        }
        return questionVoList;
    }

    public QuestionVo buildVo(Question question) {
        List<Answer> answers = JSONArray.parseArray(question.getAnswer(), Answer.class);
        Collections.shuffle(answers);
        QuestionVo questionVo = new QuestionVo();
        questionVo.setId(question.getId());
        questionVo.setContent(question.getContent());
        questionVo.setAnswers(answers);
        questionVo.setSingle(question.getSingle());
        return questionVo;
    }

    /**
     * 个人信息
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/submitExam")
    @ResponseBody
    @CrossOrigin
    public Response submitExam(HttpServletRequest request, HttpServletResponse response, @RequestBody() JSONObject paper) {
        List<Question> questionList = questionService.listByConditions(new QuestionQuery());
        Map<String, Question> allQuestion = new HashMap<>();
        for (Question question : questionList) {
            allQuestion.put(question.getId().toString(), question);
        }

        JSONObject answers = paper.getJSONObject("answers");
        Integer scores = getScores(answers, allQuestion);
        PersonInfo personInfo = new PersonInfo();
        personInfo.setScores(scores);
        String phone = paper.getString("phone");
        Integer surplusTime = paper.getInteger("surplusTime");
        Integer maxTime = 12 * 60;
        if (surplusTime < 0) {
            personInfo.setTime(maxTime);
        } else {
            personInfo.setTime(maxTime - surplusTime);
        }
        personInfo.setPhone(phone);
        personInfoService.updateByPhone(personInfo);
        return Response.ok();
    }

    /**
     * 个人信息
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/personRank")
    @ResponseBody
    @CrossOrigin
    public Response personRank(HttpServletRequest request, HttpServletResponse response) {
        String phone = request.getParameter("phone");
        PersonInfo personInfo = personInfoService.getPersonInfoByPhone(phone);
        Hospital hospital = hospitalService.getById(personInfo.getHospital());
        personInfo.setHospitalName(hospital.getHospitalname());
        return Response.ok(personInfo);
    }

    /**
     * 个人信息
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/allRank")
    @ResponseBody
    @CrossOrigin
    public Response allRank(HttpServletRequest request, HttpServletResponse response) {
        List<PersonInfo> personalRank = personInfoService.getPersonalRank();
        List<HospitalRank> hospitalRank = hospitalService.getHospitalRank(personalRank);

        HashMap map = new HashMap();
        map.put("personalRank", personalRank);
        map.put("hospitalRank", hospitalRank);
        return Response.ok(map);
    }

    public Integer getScores(JSONObject answers, Map<String, Question> allQuestion) {
        Integer scores = 0;

        Iterator<String> keys = answers.keySet().iterator();
        while (keys.hasNext()) {
            //获取选择答案数组
            String key = keys.next();
            JSONArray selectAnswers = answers.getJSONArray(key);
            Set<String> set = new HashSet<>();
            for (int i = 0; i < selectAnswers.size(); i++) {
                // 答案信息
                set.add(selectAnswers.getString(i));
            }
            Question question = allQuestion.get(key);
            JSONArray allAnswers = JSON.parseArray(question.getAnswer());
            boolean isCorrect = true;
            if (question.getSingle().equals("true")) {
                isCorrect = getSingle(allAnswers, set);
            } else {
                isCorrect = getMultiple(allAnswers, set);
            }

            if (isCorrect) {
                scores = scores + Integer.valueOf(question.getScore());
            }
        }
        return scores;
    }

    public Boolean getSingle(JSONArray allAnswers, Set<String> set) {
        //遍历比对答案
        for (int i = 0; i < allAnswers.size(); i++) {
            JSONObject iteration = allAnswers.getJSONObject(i);
            //遍历题目所有答案
            if (iteration.getBoolean("correct")) {
                //判断正确的答案是否被用户选择
                if (set.contains(iteration.getString("no"))) {
                    return true;
                } else {
                    return false;
                }
            }
        }
        return true;
    }

    public Boolean getMultiple(JSONArray allAnswers, Set<String> set) {
        boolean isCorrect = true;
        //遍历比对答案
        for (int i = 0; i < allAnswers.size(); i++) {
            JSONObject iteration = allAnswers.getJSONObject(i);
            //遍历题目所有答案
            if (iteration.getBoolean("correct")) {
                //判断正确的答案是否被用户选择
                if (!set.contains(iteration.getString("no"))) {
                    isCorrect = false;
                    break;
                }
            } else {
                //判断错误的答案是否被用户选择
                if (set.contains(iteration.getString("no"))) {
                    isCorrect = false;
                    break;
                }
            }
        }
        return isCorrect;
    }

}